﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.Linq.Expressions;
using LOMBARDISPICK.Model.Infrastructure;
using LOMBARDISPICK.Model.Repositories;
using System.Reflection;
using System.Web.Mvc;

namespace LOMBARDISPICK.Domain.Infrastructure
{
	/// <summary>
	/// Domain logic will be encapsolated in the service layer to allow an agnostic 
	/// implementation of our data model.  This class contains a generic implementation
	/// of the service class.  It will be inheriteded and used aby all other service
	/// classes as a base class
	/// </summary>
	/// <typeparam name="T">T is the Type of the entity</typeparam>
	/// <typeparam name="U">U is the Repository Type</typeparam>
	public abstract class ServiceBase<T, U>
		where T : class
		where U : IRepository<T>
	{
		protected readonly U repository;

		protected ServiceBase(IUnitOfWork unitOfWork, U repository)
		{
			this.unitOfWork = unitOfWork;
			this.repository = repository;
		}

		//private set protected get (accessible through inheritance in child classes).
		protected IUnitOfWork unitOfWork
		{
			get;
			private set;
		}

		#region ServiceBase Members
		public virtual IEnumerable<T> getAll()
		{
			var entities = this.repository.getAll();
			return entities;
		}

		public virtual IEnumerable<T> getMany(Expression<Func<T, bool>> where)
		{
			IEnumerable<T> entities = this.repository.getMany(where);
			return entities;
		}

		public abstract IEnumerable<T> getManySorted(Expression<Func<T, bool>> where);

		public abstract IEnumerable<T> getAllSorted();

		public virtual T getById(int id)
		{
			var entity = this.repository.getById(id);
			return entity;
		}

		public virtual void create(T entity)
		{
			this.repository.add(entity);
			this.save();
		}

		public virtual void delete(int id)
		{
			var entity = this.repository.getById(id);
			this.repository.delete(entity);
			this.save();
		}

		public virtual void save()
		{
			this.unitOfWork.Commit();
		}

		public virtual SelectList ViewDataSelectLists()
		{
			return new SelectList(Enumerable.Empty<string>());
		}
		public virtual SelectList ViewDataSelectLists(int versionID)
		{
			return new SelectList(Enumerable.Empty<string>());
		}
		public virtual SelectList ViewDataSelectLists(Expression<Func<T, bool>> where)
		{
			return new SelectList(Enumerable.Empty<string>());
		}
		public virtual SelectList ViewDataSelectLists(Expression<Func<T, bool>> where, int versionID)
		{
			return new SelectList(Enumerable.Empty<string>());
		}
		public virtual SelectList ViewDataSelectListsWithDefaultValue(int id)
		{
			return new SelectList(Enumerable.Empty<string>());
		}
		public virtual SelectList ViewDataSelectListsWithDefaultValue(int id, int versionID)
		{
			return new SelectList(Enumerable.Empty<string>());
		}
		public virtual SelectList ViewDataSelectListsWithDefaultValue(Expression<Func<T, bool>> where, int id)
		{
			return new SelectList(Enumerable.Empty<string>());
		}
		public virtual SelectList ViewDataSelectListsWithDefaultValue(Expression<Func<T, bool>> where, int id, int versionID)
		{
			return new SelectList(Enumerable.Empty<string>());
		}
		public virtual String ViewDataDefaultValue(int id)
		{
			return "";
		}
		public virtual SelectList ViewDataSelectListsWithDefaultValue(int? id)
		{
			return new SelectList(Enumerable.Empty<string>());
		}
		public virtual SelectList ViewDataSelectListsWithDefaultValue(int? id, int versionID)
		{
			return new SelectList(Enumerable.Empty<string>());
		}
		public virtual String ViewDataDefaultValue(int? id)
		{
			return "";
		}
		public virtual IEnumerable<SelectListItem> getSelectList()
		{
			return new SelectList(Enumerable.Empty<string>());
		}
		public virtual IEnumerable<SelectListItem> getSelectList(int versionID)
		{
			return new SelectList(Enumerable.Empty<string>());
		}
		public virtual IEnumerable<SelectListItem> getManySelectList(Expression<Func<T, bool>> where)
		{
			return new SelectList(Enumerable.Empty<string>());
		}
		public virtual IEnumerable<SelectListItem> getManySelectList(int versionID, Expression<Func<T, bool>> where)
		{
			return new SelectList(Enumerable.Empty<string>());
		}
		//public virtual Func<T, SelectListItem> StandardSelectListOptionsExpression = x => new SelectListItem
		//{
		//    Value = "",
		//    Text = ""
		//};
		public virtual Func<T, SelectListItem> StandardSelectListOptionsExpression(bool IsSelected)
		{
			return u =>
					new SelectListItem
					{
						Selected = IsSelected,
						Value = "",
						Text = ""
					};
		}
		#endregion
	}
}
